<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>原型链继承</title>
</head>
<body>
<script>
/*
  https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
  对于有基于类的语言经验的开发人员来说, JavaScript 有点令人困惑 (如Java或C ++) ，因为它是动态的，并且本身不提供一个类实现.。(在ES2015/ES6中引入了class关键字，但只是语法糖，JavaScript 仍然是基于原型的)。
  当谈到继承时，Javascript 只有一种结构：对象。每个对象都有一个私有属性(称为[[Prototype]]), 它持有一个连接到另一个称为其 prototype 对象的链接。该原型对象具有一个自己的原型，等等，直到达到一个对象的 prototype 为 null。根据定义，null 没有 prototype，并作为这个原型链 中的最后一个环节。
  JavaScript中几乎所有的对象都是位于原型链顶端的Object的实例。
  原型继承经常被视为 JavaScript 的一个弱点，但事实上，原型继承模型比经典的继承模型更加强大。例如，在一个原型模型之上构建一个经典模型是相当容易的
  基于原型链的继承
  继承属性
  JavaScript 对象是动态的属性“包”（指其自己的属性）。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时，它不仅仅在该对象上搜寻，还会搜寻该对象的原型，以及该对象的原型的原型，依次层层向上搜索，直到找到一个名字匹配的属性或到达原型链的末尾。
  继承方法
  JavaScript 并没有其他基于类的语言所定义的“方法”。在 JavaScript 里，任何函数都可以添加到对象上作为对象的属性。函数的继承与其他的属性继承没有差别，包括上面的“属性覆盖”（这种情况相当于其他语言的方法重写）。
  当继承的函数被调用时，this 指向的是当前继承的对象，而不是继承的函数所在的原型对象。
*/
  var o = {
    a: 2,
    m: function(){
      return this.a + 1;
    }
  }
  console.log(o)
  var p = Object.create(o)
  console.log(p)
  p.a = 12
  
  console.log(p)

//2:借用原型链实现继承
//缺点：原型对象的属性是共享的
function Animal(){
  this.eat  =function(){
    console.log('eat')
  }
}
function Dog(){
  this.bark = function(){
    console.log('bark')
  }
}
Dog.prototype = new Animal()
var hashiqi = new Dog();
hashiqi.bark()
</script>
</body>
</html>